package com.zyh.scs.admin.service.impl.temporary;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zyh.scs.admin.api.constant.CodeSet;
import com.zyh.scs.admin.api.constant.QWPullStatus;
import com.zyh.scs.admin.api.constant.UserStateEnum;
import com.zyh.scs.admin.api.dto.fanWei.FanWeiQueryDto;
import com.zyh.scs.admin.api.entity.*;
import com.zyh.scs.admin.api.entity.temporary.TemporaryDepartmentInfo;
import com.zyh.scs.admin.api.entity.temporary.TemporaryPsnInfo;
import com.zyh.scs.admin.api.entity.temporary.TemporaryStaffInfo;
import com.zyh.scs.admin.base.LaoSheFanWeiResponse;
import com.zyh.scs.admin.mapper.*;
import com.zyh.scs.admin.service.*;
import com.zyh.scs.admin.utils.FanWeiReqUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @author hwh
 * @ClassName: 临时拉去泛微数据存到临时表中$
 * @Description: $
 * @Date $
 * @Version 1.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class PullFanWeiTemporaryService {

    /**
     * [泛微OA API] 3. 人员档案信息
     */
    @Value("${fanWei.api.pull-psnInfo}")
    public String API_FANWEI_PULL_PSNINFO;

    /**
     * [泛微OA API] 1. 人员任职信息
     */
    @Value("${fanWei.api.pull-zhyInfo}")
    public String API_FANWEI_PULL_ZHYINFO;

    /**
     * [泛微OA API] 2. 组织机构信息
     */
    @Value("${fanWei.api.pull-department}")
    public String API_FANWEI_PULL_DEPARTMENT;

    private final FanWeiReqUtil fanWeiReqUtil;

    private final SysUserMapper sysUserMapper;

    /**
     * 部门临时表
     */
    private final TemporaryDepartmentInfoService temporaryDepartmentInfoService;

    /**
     * 人员临时表
     */
    private final TemporaryPsnInfoService temporaryPsnInfoService;

    /**
     * 任职信息
     */
    private final TemporaryStaffInfoService temporaryStaffInfoService;

    /**
     * 部门表
     */
    private final UserDepartmentInfoMapper userDepartmentInfoMapper;

    /**
     * 人员临时表
     */
    private final UserPsnInfoService userPsnInfoService;

    /**
     * 任职信息
     */
    private final UserStaffInfoMapper userStaffInfoMapper;

    /**
     * 岗位
     */
    private final SysPostMapper sysPostMapper;

    private final SysUserService userService;

    private final UserEarlyWarnService userEarlyWarnService;

    private final UserEarlyWarnMapper userEarlyWarnMapper;

    /**
     * redis客户端
     */
    private final RedissonClient redissonClient;

    private final String USER_TASK_KEY = "USER_TASK_KEY";


    /**
     * 同步线程池
     *
     * @return
     */
    public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //配置核心线程数
        executor.setCorePoolSize(20);
        //配置最大线程数
        executor.setMaxPoolSize(100);
        //配置队列大小
        executor.setQueueCapacity(200);
        //线程池维护线程所允许的空闲时间
        executor.setKeepAliveSeconds(30);
        //配置线程池中的线程的名称前缀
        executor.setThreadNamePrefix("Async-Thread-SyncFanWei-");
        //设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean
        executor.setWaitForTasksToCompleteOnShutdown(true);
        //设置线程池中任务的等待时间，如果超过这个时候还没有销毁就强制销毁，以确保应用最后能够被关闭，而不是阻塞住
        executor.setAwaitTerminationSeconds(60);
        // rejection-policy：当pool已经达到max size的时候，如何处理新任务
        // CALLER_RUNS：不在新线程中执行任务，而是由调用者所在的线程来执行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //执行初始化
        executor.initialize();
        return executor;
    }


    /**
     * 获取泛微 部门  人员  职务 total
     */
    public void pullAccount() {
        //部门
        FanWeiQueryDto queryDto = new FanWeiQueryDto();

        queryDto.setPageIndex(1);
        queryDto.setPageSize(10);
        fanWeiReqUtil.queryReqAccount(API_FANWEI_PULL_ZHYINFO, queryDto);
        log.info("泛微数据： {}",fanWeiReqUtil.queryReqAccount(API_FANWEI_PULL_ZHYINFO, queryDto));
    }

    /**
     * 通过 页码和页数  type 1为部门  2为人员  3任职
     *
     * @param
     * @return
     */
    public LaoSheFanWeiResponse<JSONArray> pullToSize(Integer pageIndex, Integer pageSize, Integer type) {

        JSONArray jsonArray = new JSONArray();

        FanWeiQueryDto queryDto = new FanWeiQueryDto();
        queryDto.setPageIndex(pageIndex);
        queryDto.setPageSize(pageSize);

        if (type == 1) {
            jsonArray = fanWeiReqUtil.queryReqAccount(API_FANWEI_PULL_DEPARTMENT, queryDto).getData();
            log.info("[API: 泛微OA-获取部门列表] <<<<<< url: {}, result: {},pageIndex: {}, pageSize: {}", API_FANWEI_PULL_DEPARTMENT, jsonArray, pageIndex, pageSize);
        } else if (type == 2) {
            jsonArray = fanWeiReqUtil.queryReqAccount(API_FANWEI_PULL_PSNINFO, queryDto).getData();
            log.info("[API: 泛微OA-获取人员列表] <<<<<< url: {}, result: {},pageIndex: {}, pageSize: {}", API_FANWEI_PULL_PSNINFO, jsonArray, pageIndex, pageSize);
        } else if (type == 3) {
            jsonArray = fanWeiReqUtil.queryReqAccount(API_FANWEI_PULL_ZHYINFO, queryDto).getData();
            log.info("[API: 泛微OA-获取职务列表] <<<<<< url: {}, result: {},pageIndex: {}, pageSize: {}", API_FANWEI_PULL_ZHYINFO, jsonArray, pageIndex, pageSize);
        }

        return LaoSheFanWeiResponse.successData(jsonArray);
    }


    /**
     * 拉取部门 存到临时表中
     *
     * @param pageIndex
     * @return
     */
    public LaoSheFanWeiResponse<JSONArray> pullFanWeiDepartment(Integer pageIndex) {
        // 1.获取部门列表
        FanWeiQueryDto queryDto = new FanWeiQueryDto();

        queryDto.setPageIndex(pageIndex);
        queryDto.setPageSize(1000);

        LaoSheFanWeiResponse<JSONArray> queryResp = fanWeiReqUtil.queryReq(API_FANWEI_PULL_DEPARTMENT, queryDto);
        log.info("[API: 泛微OA-获取部门列表] <<<<<< url: {}, result: {}", API_FANWEI_PULL_DEPARTMENT, queryResp.getRetCode());

        if (!Objects.equals(CodeSet.SUCCESS_CODE.getCode(), queryResp.getRetCode())) {
            log.info("[同步泛微OA部门] <<<<<< 同步失败，泛微OA接口响应失败");
            return LaoSheFanWeiResponse.error(CodeSet.SYSTEM_ERR_CODE.getCode(), "同步失败，调用泛微OA接口失败");
        }

        return LaoSheFanWeiResponse.successData(queryResp.getData());
    }

    /**
     * 同步/更新 泛微OA部门/人员
     *
     * @return
     */
    public void pullFanWei() {

        RLock lock = redissonClient.getLock(USER_TASK_KEY + "pullFanWei");
        log.info("定时-同步/更新 泛微OA部门/人员 <<<<< 开始时间: {}", LocalDateTime.now());

        try {
            lock.lock(20, TimeUnit.SECONDS);
//            log.info("1.1 定时获取泛微 部门 人员  职务 数量 <<<<< 开始时间: {}", LocalDateTime.now());
//            //先获取泛微 部门 人员  职务 数量
//            pullAccount();
//            log.info("1.2 定时获取泛微 部门 人员  职务 数量 <<<<< 结束时间: {}", LocalDateTime.now());
            log.info("1.3 定时获取部门  人员  职务到临时表中 <<<<< 开始时间: {}", LocalDateTime.now());
            //首先拉取部门  人员  职务到临时表中
            pullTemporaryFanWei();
            log.info("1.4 定时获取部门  人员  职务到临时表中 <<<<< 结束时间: {}", LocalDateTime.now());

        } catch (Exception e) {
            log.error("定时-同步/更新 :泛微OA部门/人员 异常: {}", e.getMessage());
        } finally {
            if (lock.isLocked() && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
        log.info("定时-同步/更新 泛微/人员 <<<<< 结束时间: {}", LocalDateTime.now());
    }


    /**
     * 更新到部门表和用户任职表中
     *
     * @return
     */
    public void insertNew() {

        log.info("更新到部门表和用户任职表中 <<<<< 开始时间: {}", LocalDateTime.now());

        //加redis 定位任务锁
        RLock lock = redissonClient.getLock(USER_TASK_KEY + "insertNew");
        try {

            lock.lock(10, TimeUnit.SECONDS);
            //从临时表中insert到部门表中
            log.info("1.5 从临时表中insert到部门表中 <<<<< 开始时间: {}", LocalDateTime.now());
            insertDepartment();
            log.info("1.6 从临时表中insert到部门表中 <<<<< 结束时间: {}", LocalDateTime.now());
            //从临时表中insert到人员表中
            log.info("1.7 从临时表中insert到人员表中 <<<<< 开始时间: {}", LocalDateTime.now());
            insertPsnUser();
            log.info("1.9 从临时表中insert到任职表中 <<<<< 结束时间: {}", LocalDateTime.now());
            //从临时表中insert到任职表中
            log.info("2.0 从临时表中insert到任职表中 <<<<< 开始时间: {}", LocalDateTime.now());
            insertStaff();
            log.info("2.1 从临时表中insert到任职表中 <<<<< 结束时间: {}", LocalDateTime.now());


        } catch (Exception e) {
            log.error("更新到部门表和用户任职表中 异常: {}", e.getMessage());
        } finally {
            if (lock.isLocked() && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
        log.info("更新到部门表和用户任职表中 <<<<< 结束时间: {}", LocalDateTime.now());
    }

    /**
     * 拉取人员 存到临时表中
     *
     * @param pageIndex
     * @return
     */
    public LaoSheFanWeiResponse<JSONArray> pullFanWeiUserPsn(Integer pageIndex) {
        // 1.获取人员档案列表
        FanWeiQueryDto queryDto = new FanWeiQueryDto();

        queryDto.setPageIndex(pageIndex);
        queryDto.setPageSize(1000);

        LaoSheFanWeiResponse<JSONArray> queryResp = fanWeiReqUtil.queryReq(API_FANWEI_PULL_PSNINFO, queryDto);
        log.info("[API: 泛微OA-获取人员档案列表] <<<<<< url: {}, result: {}", API_FANWEI_PULL_PSNINFO, queryResp.getRetCode());

        if (!Objects.equals(CodeSet.SUCCESS_CODE.getCode(), queryResp.getRetCode())) {
            log.info("[同步泛微OA人员档案] <<<<<< 同步失败，泛微OA接口响应失败");
            return LaoSheFanWeiResponse.error(CodeSet.SYSTEM_ERR_CODE.getCode(), "同步失败，调用泛微OA接口失败");
        }

        return LaoSheFanWeiResponse.successData(queryResp.getData());
    }

    /**
     * 同步泛微OA人员-人员任职信息
     *
     * @return
     */
    public LaoSheFanWeiResponse<JSONArray> pullFanWeiUserZhy(Integer pageIndex) {

        // 1.获取人员任职列表
        FanWeiQueryDto queryDto = new FanWeiQueryDto();

        queryDto.setPageIndex(pageIndex);
        queryDto.setPageSize(1000);

        LaoSheFanWeiResponse<JSONArray> queryResp = fanWeiReqUtil.queryReq(API_FANWEI_PULL_ZHYINFO, queryDto);

        log.info("[API: 泛微OA-获取人员任职列表] <<<<<< url: {}, result: {}", API_FANWEI_PULL_ZHYINFO, queryResp.getRetCode());

        if (!Objects.equals(CodeSet.SUCCESS_CODE.getCode(), queryResp.getRetCode())) {
            log.info("[同步泛微OA人员任职] <<<<<< 同步失败，泛微OA接口响应失败");
            return LaoSheFanWeiResponse.error(CodeSet.SYSTEM_ERR_CODE.getCode(), "同步失败，调用泛微OA接口失败");
        }

        return LaoSheFanWeiResponse.successData(queryResp.getData());
    }

    /**
     * 首先拉取部门  人员  职务到临时表中
     */
    public void pullTemporaryFanWei() {

        int deptPage = 1;
        int psnPage = 1;
        int staffPage = 1;


        //部门
        log.info("同步泛微OA部门到临时表中 开始时间 time:{}", LocalDateTime.now());
        while (true) {
            log.info("部门拉取页数：{}",deptPage);
            JSONArray departmentArr = pullFanWeiDepartment(deptPage).getData();
            if (null == departmentArr || departmentArr.isEmpty()) {
                log.info("[同步泛微OA部门] <<<<<< 同步失败，部门数据为空");
                break;
            }

            log.info("同步泛微OA部门数量:{}", departmentArr.size());
            for (int i = 0, len = departmentArr.size(); i < len; i++) {

                JSONObject departmentJSON = departmentArr.getJSONObject(i);

                if (null == departmentJSON) {
                    continue;
                }

                // 组织机构标识
                String deptId = departmentJSON.getString("dept_id");

                if (StrUtil.isEmpty(deptId)) {
                    continue;
                }

                Date now = new Date();

                // 新增部门
                TemporaryDepartmentInfo ufDepartInsert = new TemporaryDepartmentInfo();

                ufDepartInsert.setIndbDate(departmentJSON.getString("indb_date"));
                ufDepartInsert.setApplyEvent(departmentJSON.getString("apply_event"));
                ufDepartInsert.setDeptId(departmentJSON.getString("dept_id"));
                ufDepartInsert.setOrgCode(departmentJSON.getString("org_code"));
                ufDepartInsert.setOrgName(departmentJSON.getString("org_name"));
                ufDepartInsert.setOrgShortName(departmentJSON.getString("org_short_name"));
                ufDepartInsert.setOrgEnName(departmentJSON.getString("org_en_name"));
                ufDepartInsert.setOrgLevel(departmentJSON.getString("org_level"));
                ufDepartInsert.setOrgType(departmentJSON.getString("org_type"));
                ufDepartInsert.setParentId(departmentJSON.getString("parent_id"));
                ufDepartInsert.setParentCode(departmentJSON.getString("parent_code"));
                ufDepartInsert.setChargePersonCode(departmentJSON.getString("charge_person"));
                ufDepartInsert.setOrgOrder(departmentJSON.getString("org_order"));
                ufDepartInsert.setOrgStatus(departmentJSON.getString("org_status"));

                ufDepartInsert.setPullDate(now);
                ufDepartInsert.setPullStatus(QWPullStatus.UNSYNC.getCode());
                ufDepartInsert.setMasterCreateTime(LocalDateTime.now());
                ufDepartInsert.setModifyTime(now);
                ufDepartInsert.setCreateTime(now);
                ufDepartInsert.setIsInsert(2);

                temporaryDepartmentInfoService.save(ufDepartInsert);
            }
            deptPage++;
        }
        log.info("同步泛微OA部门到临时表中 结束时间 time:{}", LocalDateTime.now());

        //人员
        log.info("同步泛微OA人员到临时表中 开始时间 time:{}", LocalDateTime.now());

        while (true) {
            log.info("人员拉取页数：{}",psnPage);
            JSONArray psninfoArr = pullFanWeiUserPsn(psnPage).getData();
            log.info("同步泛微OA人员档案结果:{}", psninfoArr);
            if (null == psninfoArr || psninfoArr.isEmpty()) {
                log.info("[同步泛微OA人员档案] <<<<<< 同步失败，人员档案数据为空");
                break;
            }

            log.info("同步泛微OA人员档案数量:{}", psninfoArr.size());
            for (int i = 0, len = psninfoArr.size(); i < len; i++) {

                JSONObject psninfoJSON = psninfoArr.getJSONObject(i);

                if (null == psninfoJSON) {
                    continue;
                }

                // 员工标识
                String psnId = psninfoJSON.getString("psn_id");

                if (StrUtil.isEmpty(psnId)) {
                    continue;
                }

                // 2.同步更新 人员档案相关表
                Date now = new Date();
                TemporaryPsnInfo ufPsnInfoInsert = new TemporaryPsnInfo();

                ufPsnInfoInsert.setIndbDate(psninfoJSON.getString("indb_date"));
                ufPsnInfoInsert.setApplyEvent(psninfoJSON.getString("apply_event"));
                ufPsnInfoInsert.setPsnId(psninfoJSON.getString("psn_id"));
                ufPsnInfoInsert.setPsnCode(psninfoJSON.getString("psn_code"));
                ufPsnInfoInsert.setPsnName(psninfoJSON.getString("psn_name"));
                ufPsnInfoInsert.setPsnNamePy(psninfoJSON.getString("psn_name_py"));
                ufPsnInfoInsert.setPsnEnName(psninfoJSON.getString("psn_en_name"));
                ufPsnInfoInsert.setSex(psninfoJSON.getString("sex"));
                ufPsnInfoInsert.setBirthDate(psninfoJSON.getString("birth_date"));
                ufPsnInfoInsert.setHomeAddress(psninfoJSON.getString("home_address"));
                ufPsnInfoInsert.setMobile(psninfoJSON.getString("mobile"));
                ufPsnInfoInsert.setEmail(psninfoJSON.getString("email"));
                ufPsnInfoInsert.setOfficePhone(psninfoJSON.getString("office_phone"));
                ufPsnInfoInsert.setJoinWorkDate(psninfoJSON.getString("join_work_date"));
                ufPsnInfoInsert.setSsdate(psninfoJSON.getString("ssdate"));
                ufPsnInfoInsert.setSsnum(psninfoJSON.getString("ssnum"));
                ufPsnInfoInsert.setIndbDate(psninfoJSON.getString("induty_date"));
                ufPsnInfoInsert.setRegularDate(psninfoJSON.getString("regular_date"));
                ufPsnInfoInsert.setSalaryLevel(psninfoJSON.getString("salary_level"));
                ufPsnInfoInsert.setSalaryGrade(psninfoJSON.getString("salary_grade"));
                ufPsnInfoInsert.setBankName(psninfoJSON.getString("bank_name"));
                ufPsnInfoInsert.setBankBranch(psninfoJSON.getString("bank_branch"));
                ufPsnInfoInsert.setBankNo(psninfoJSON.getString("bank_no"));
                ufPsnInfoInsert.setLineNo(psninfoJSON.getString("line_no"));
                ufPsnInfoInsert.setStationNo(psninfoJSON.getString("station_no"));
                ufPsnInfoInsert.setPhotoUrl(psninfoJSON.getString("photo_url"));
                ufPsnInfoInsert.setPhotoSmallUrl(psninfoJSON.getString("photo_small_url"));
                ufPsnInfoInsert.setPsnLevel(psninfoJSON.getString("psn_level"));
                ufPsnInfoInsert.setWorkAddress(psninfoJSON.getString("work_address"));
                ufPsnInfoInsert.setPsnOrder(psninfoJSON.getString("psn_order"));
                ufPsnInfoInsert.setIdcard(psninfoJSON.getString("idcard"));

                ufPsnInfoInsert.setPullDate(now);
                ufPsnInfoInsert.setPullStatus(QWPullStatus.UNSYNC.getCode().toString());
                ufPsnInfoInsert.setCreateTime(now);
                ufPsnInfoInsert.setModifyTime(now);
                ufPsnInfoInsert.setId(System.currentTimeMillis());
                ufPsnInfoInsert.setIsInsert(2);
                ufPsnInfoInsert.setMasterCreateTime(LocalDateTime.now());
                temporaryPsnInfoService.save(ufPsnInfoInsert);
            }
            psnPage++;
        }

        log.info("同步泛微OA人员到临时表中 结束时间 time:{}", LocalDateTime.now());

        //职务
        log.info("同步泛微OA职务到临时表中 开始时间 time:{}", LocalDateTime.now());
        while (true) {

            log.info("职务拉取页数：{}",staffPage);

            JSONArray zhyinfoArr = pullFanWeiUserZhy(staffPage).getData();

            log.info("页码:{},同步泛微OA人员任职结果 :{}", zhyinfoArr, staffPage);
            if (null == zhyinfoArr || zhyinfoArr.isEmpty()) {
                log.info("[同步泛微OA人员任职] <<<<<< 同步失败，人员任职数据为空");
                break;
            }
            for (int i = 0, len = zhyinfoArr.size(); i < len; i++) {

                JSONObject zhyinfoJSON = zhyinfoArr.getJSONObject(i);

                if (null == zhyinfoJSON) {
                    continue;
                }

                // 员工标识
                String psnId = zhyinfoJSON.getString("psn_id");

                if (StrUtil.isEmpty(psnId)) {
                    continue;
                }
                // 2.同步更新 人员任职相关表
                Date now = new Date();

                TemporaryStaffInfo ufZhyInfoInsert = new TemporaryStaffInfo();

                ufZhyInfoInsert.setDutyId(zhyinfoJSON.getString("duty_id"));
                ufZhyInfoInsert.setPsnId(zhyinfoJSON.getString("psn_id"));
                ufZhyInfoInsert.setApplyEvent(zhyinfoJSON.getString("apply_event"));
                ufZhyInfoInsert.setCorpId(zhyinfoJSON.getString("corp_id"));
                ufZhyInfoInsert.setDeptId(zhyinfoJSON.getString("dept_id"));
                ufZhyInfoInsert.setOrgCode(zhyinfoJSON.getString("org_code"));
                ufZhyInfoInsert.setIndutyDate(zhyinfoJSON.getString("induty_date"));
                ufZhyInfoInsert.setOnpostDate(zhyinfoJSON.getString("onpost_date"));
                ufZhyInfoInsert.setPnsClass(zhyinfoJSON.getString("pns_class"));
                ufZhyInfoInsert.setPnsClassName(zhyinfoJSON.getString("pns_class_name"));
                ufZhyInfoInsert.setPnsJob(zhyinfoJSON.getString("pns_job"));
                ufZhyInfoInsert.setIsLeader(zhyinfoJSON.getString("is_leader"));
                ufZhyInfoInsert.setPnsOrder(zhyinfoJSON.getString("pns_order"));
                ufZhyInfoInsert.setClassPosition(zhyinfoJSON.getString("class_position"));
                ufZhyInfoInsert.setGradePosition(zhyinfoJSON.getString("grade_position"));
                ufZhyInfoInsert.setDutyCode(zhyinfoJSON.getString("duty_code"));
                ufZhyInfoInsert.setDutyType(zhyinfoJSON.getString("duty_type"));
                ufZhyInfoInsert.setJobCode(zhyinfoJSON.getString("job_code"));
                ufZhyInfoInsert.setJobStatus(zhyinfoJSON.getString("job_status"));
                ufZhyInfoInsert.setBeginTime(zhyinfoJSON.getString("begin_time"));
                ufZhyInfoInsert.setEndTime(zhyinfoJSON.getString("end_time"));

                ufZhyInfoInsert.setPullDate(now);
                ufZhyInfoInsert.setPullStatus(QWPullStatus.UNSYNC.getCode().toString());
                ufZhyInfoInsert.setCreateTime(now);
                ufZhyInfoInsert.setModifyTime(now);
                ufZhyInfoInsert.setId(System.currentTimeMillis());
                ufZhyInfoInsert.setMasterCreateTime(LocalDateTime.now());
                ufZhyInfoInsert.setIsInsert(2);
                temporaryStaffInfoService.save(ufZhyInfoInsert);
            }
            staffPage++;
        }
        log.info("同步泛微OA职务到临时表中 结束时间 time:{}", LocalDateTime.now());

    }

    /**
     * 更新psn人员信息表到用户表
     */
    public void updatePsnUser() {

        //加redis 定位任务锁
        RLock lock = redissonClient.getLock(USER_TASK_KEY + "updatePsnUser");

        try {

            lock.lock(10, TimeUnit.SECONDS);

            List<UserPsnInfo> userPsnInfoList = userPsnInfoService
                    .list(Wrappers.<UserPsnInfo>lambdaQuery()
                            .eq(UserPsnInfo::getIsInsert, 2)
                            .in(UserPsnInfo::getApplyEvent, "1", "2"));

            List<UserStaffInfo> userStaffInfoList = userStaffInfoMapper.selectList(Wrappers.<UserStaffInfo>lambdaQuery()
                    .in(UserStaffInfo::getApplyEvent,"1","2"));
            Map<String, List<UserStaffInfo>> staffMap = userStaffInfoList.stream().filter(Objects::nonNull)
                    .collect(Collectors.groupingBy(UserStaffInfo::getPsnId));

            List<SysPost> sysPostList = sysPostMapper.selectList(null);
            Map<String, List<SysPost>> postMap = sysPostList.stream()
                    .filter(Objects::nonNull)
                    .collect(Collectors.groupingBy(SysPost::getPostCode));

            List<UserDepartmentInfo> userDepartmentInfoList = userDepartmentInfoMapper.selectList(null);
            Map<String, List<UserDepartmentInfo>> departmentMap = userDepartmentInfoList.stream()
                    .filter(Objects::nonNull)
                    .filter(de -> StrUtil.isNotBlank(de.getDeptId()))
                    .collect(Collectors.groupingBy(UserDepartmentInfo::getDeptId));

            //更新表中
            List<SysUser> sysUserList = sysUserMapper
                    .selectList(Wrappers.<SysUser>lambdaQuery()
                            .eq(SysUser::getDataSources, 1));

            Map<String, List<SysUser>> userMap = sysUserList.stream()
                    .filter(Objects::nonNull)
                    .filter(a -> StrUtil.isNotBlank(a.getPsnId()))
                    .collect(Collectors.groupingBy(SysUser::getPsnId));

            List<String> psnList = new ArrayList<>();

            if (!sysUserList.isEmpty()) {
                psnList = sysUserList.stream().filter(Objects::nonNull).map(SysUser::getPsnId).toList();
            }

            List<SysUser> userAddList = new ArrayList<>();
            List<SysUser> userUpdateList = new ArrayList<>();

            AtomicInteger indexAdd = new AtomicInteger(1);
            AtomicInteger indexUpdate = new AtomicInteger(1);

            for (UserPsnInfo userPsnInfo : userPsnInfoList) {
                if (userPsnInfo == null) {
                    continue;
                }

                SysUser sysUserUpdate = new SysUser();
                if (psnList.contains(userPsnInfo.getPsnId())) {
                    List<SysUser> userList = userMap.get(userPsnInfo.getPsnId());
                    if (CollectionUtil.isNotEmpty(userList)) {
                        if (userList.get(0) != null) {
                            sysUserUpdate = userList.get(0);
                        }
                    }
                }

                SysUser sysUserAdd = new SysUser();
                sysUserAdd.setUserType(1);
                sysUserAdd.setDataSources("1");
                sysUserUpdate.setUserType(1);
                sysUserUpdate.setDataSources("1");
                sysUserAdd.setUpdateTime(LocalDateTime.now());
                sysUserUpdate.setUpdateTime(LocalDateTime.now());
                sysUserAdd.setPsnId(userPsnInfo.getPsnId());
                sysUserAdd.setUserJobNumber(userPsnInfo.getPsnCode());
                sysUserUpdate.setUserJobNumber(userPsnInfo.getPsnCode());
                sysUserAdd.setCardState("1");
                sysUserAdd.setCashState("1");
                sysUserAdd.setLockFlag("0");
                sysUserAdd.setDelFlag("0");
                sysUserUpdate.setCardState("1");
                sysUserUpdate.setCashState("1");
                sysUserUpdate.setLockFlag("0");
                sysUserUpdate.setDelFlag("0");
                sysUserAdd.setGuid(IdUtil.nanoId(20));
                sysUserAdd.setPhone(StrUtil.isNotBlank(userPsnInfo.getMobile()) ? userPsnInfo.getMobile() : "");
                if (StrUtil.isNotBlank(userPsnInfo.getPsnName())) {
                    sysUserAdd.setUsername(userPsnInfo.getPsnName());
                    sysUserUpdate.setUsername(userPsnInfo.getPsnName());
                }

                List<UserStaffInfo> staffInfoList = staffMap.get(userPsnInfo.getPsnId());

                if (CollectionUtil.isNotEmpty(staffInfoList)) {
                    UserStaffInfo userStaffInfo = staffInfoList.get(0);
                    if (userStaffInfo != null) {
                        if (StrUtil.isNotBlank(userStaffInfo.getJobCode())) {
                            List<SysPost> postList = postMap.get(userStaffInfo.getJobCode());
                            if (CollectionUtil.isNotEmpty(postList)) {
                                SysPost sysPost = postList.get(0);
                                if (sysPost != null) {
                                    sysUserAdd.setPostId(sysPost.getPostId());
                                    sysUserUpdate.setPostId(sysPost.getPostId());
                                }
                            }
                        }
                        //公司
                        List<UserDepartmentInfo> companyList = departmentMap.get(userStaffInfo.getCorpId());
                        if (CollectionUtil.isNotEmpty(companyList)) {
                            UserDepartmentInfo userDepartmentInfo = companyList.get(0);
                            if (userDepartmentInfo != null) {
                                sysUserAdd.setCompanyId(userDepartmentInfo.getId());
                                sysUserUpdate.setCompanyId(userDepartmentInfo.getId());
                            }
                        }
                        //部门
                        List<UserDepartmentInfo> departmentInfoList = departmentMap.get(userStaffInfo.getDeptId());
                        if (CollectionUtil.isNotEmpty(departmentInfoList)) {
                            UserDepartmentInfo userDepartmentInfo = departmentInfoList.get(0);
//                        sysUserAdd.setDeptId(Long.parseLong(userDepartmentInfo.getDeptId()));
                            sysUserAdd.setThirdDeptId(userDepartmentInfo.getDeptId());
//                        sysUserUpdate.setDeptId(Long.parseLong(userDepartmentInfo.getDeptId()));
                            sysUserUpdate.setThirdDeptId(userDepartmentInfo.getDeptId());
                        }
                    }
                }

                if (psnList.contains(userPsnInfo.getPsnId())) {
                    log.info("用户已存在，更新用户信息 >>> 个数：{}", indexUpdate.getAndIncrement());
                    userUpdateList.add(sysUserUpdate);
                }

                if (!psnList.contains(userPsnInfo.getPsnId())) {
                    log.info("用户不存在，新增用户信息 >>> 个数：{}", indexAdd.getAndIncrement());
                    sysUserAdd.setGuid(IdUtil.nanoId(20));
                    userAddList.add(sysUserAdd);
                }

                userPsnInfo.setIsInsert(1);

            }

            userPsnInfoService.updateBatchById(userPsnInfoList);
            log.info("新增用户信息>>>  个数：{}", userAddList.size());
            userService.saveBatch(userAddList);
            log.info("更新用户信息>>>  个数：{}", userUpdateList.size());
            userService.updateBatchById(userUpdateList);
        } finally {
            if (lock.isLocked() && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }

    }


    public void lock() {
        List<UserPsnInfo> userPsnApplyList = userPsnInfoService
                .list(Wrappers.<UserPsnInfo>lambdaQuery()
                        .eq(UserPsnInfo::getIsInsert, 2)
                        .eq(UserPsnInfo::getApplyEvent, "3"));

        //查询
        List<SysUser> lockUserList = sysUserMapper.selectList(Wrappers.<SysUser>lambdaQuery()
                .eq(SysUser::getDataSources, "1"));

        List<SysUser> userLockList = new ArrayList<>();

        Map<String, List<SysUser>> lockMap = lockUserList.stream()
                .filter(Objects::nonNull)
                .filter(a -> StrUtil.isNotBlank(a.getPsnId()))
                .collect(Collectors.groupingBy(SysUser::getPsnId));

        List<String> lockPsnList = lockUserList.stream().filter(Objects::nonNull).map(SysUser::getPsnId)
                .filter(StrUtil::isNotBlank).toList();
        log.info("锁住的psnId>>>  个数：{}", userPsnApplyList.size());
        for (UserPsnInfo userPsnInfo : userPsnApplyList) {
            if (userPsnInfo == null) {
                continue;
            }

            if (StrUtil.isBlank(userPsnInfo.getPsnId())) {
                continue;
            }

            SysUser sysUserLock = new SysUser();
            if (lockPsnList.contains(userPsnInfo.getPsnId())) {
                List<SysUser> userList = lockMap.get(userPsnInfo.getPsnId());
                if (CollectionUtil.isNotEmpty(userList)) {
                    if (!userList.isEmpty()) {
                        sysUserLock = userList.get(0);
                        sysUserLock.setLockFlag(UserStateEnum.LOCK.getCode());
                        sysUserLock.setPullStatus(1);
                        sysUserLock.setCashState("2");
                        sysUserLock.setCardState("2");
                        userLockList.add(sysUserLock);
                    }
                }
            }

            userPsnInfo.setIsInsert(1);
        }

        userService.updateBatchById(userLockList);
    }

    public void warmUser() {
        //冻结泛微缺少用户
        //加redis 定位任务锁
        RLock lock = redissonClient.getLock(USER_TASK_KEY + "warmUser");

        try {

            lock.lock(10, TimeUnit.SECONDS);

            log.info("冻结泛微缺少用户 <<<<< 开始时间: {}", LocalDateTime.now());
            lock();
            log.info("冻结泛微缺少用户 <<<<< 结束时间: {}", LocalDateTime.now());
            //同步用户发送预警
            log.info("同步用户发送预警 <<<<< 开始时间: {}", LocalDateTime.now());
            earlyWarn();
            log.info("同步用户发送预警 <<<<< 结束时间: {}", LocalDateTime.now());
        } finally {
            if (lock.isLocked() && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }

    }

    public void lockControl() {
        earlyWarn();
    }

    /**
     * 发送预警
     */
    public void earlyWarn() {
        //先将未处理的预警忽略
        List<UserEarlyWarn> userEarlyWarnList = userEarlyWarnService.list(Wrappers.<UserEarlyWarn>lambdaQuery()
                .eq(UserEarlyWarn::getResult, 1));
        userEarlyWarnList.forEach(cc -> {
            cc.setResult("4");
            cc.setResultTime(LocalDateTime.now());
            cc.setOperateId("1");
            cc.setCreateBy("admin");
        });

        userEarlyWarnService.updateBatchById(userEarlyWarnList);

        List<SysUser> sysUserList = sysUserMapper.selectList(Wrappers.<SysUser>lambdaQuery()
                .eq(SysUser::getDataSources, 1)
                .eq(SysUser::getLockFlag, UserStateEnum.NORMAL.getCode()));

        Map<String, Long> jobNumberGroup = sysUserList.stream().filter(Objects::nonNull)
                .filter(item -> StrUtil.isNotBlank(item.getUserJobNumber()))
                .collect(Collectors.groupingBy(SysUser::getUserJobNumber, Collectors.counting()));
        Set<String> keySet = findKeysWithValue(jobNumberGroup);
        log.info("同步用户发送预警 <<<<< 个数: {}", keySet.size());

        //发送预警
        keySet.forEach(cc -> {
            log.info("同步用户发送预警工号 <<<<< 工号: {}", cc);
            insertWarn(sysUserMapper.selectList(Wrappers.<SysUser>lambdaQuery()
                    .eq(SysUser::getUserJobNumber, cc)
                    .eq(SysUser::getLockFlag, UserStateEnum.NORMAL.getCode())
                    .eq(SysUser::getDataSources, "1")
                    .orderByDesc(SysUser::getUpdateTime)));
        });

    }

    private void insertWarn(List<SysUser> userPsnNumberList) {
        if (CollectionUtil.isNotEmpty(userPsnNumberList)) {
            SysUser sysUser = userPsnNumberList.stream().findAny().get();
            //生成预警信息
            UserEarlyWarn userEarlyWarnNew = getUserEarlyWarn(sysUser);
            userEarlyWarnNew.setEarlyType("1");
            userEarlyWarnNew.setUserId(sysUser.getUserId());
            userEarlyWarnNew.setGuid(sysUser.getGuid());
            userEarlyWarnNew.setPhone(sysUser.getPhone());
            userEarlyWarnNew.setCardAccount(sysUser.getCardAccount());
            userEarlyWarnNew.setCashAccount(sysUser.getCashAccount());
            userEarlyWarnNew.setOperateId("1");
            userEarlyWarnMapper.insert(userEarlyWarnNew);
            List<SysUser> list = userPsnNumberList.stream()
                    .filter(f -> !f.getUserId().equals(sysUser.getUserId())).toList();
            list.forEach(job -> {
                //生成预警旧预警
                UserEarlyWarn userEarlyWarnOld = getUserEarlyWarn(job);
                userEarlyWarnOld.setCardAccount(job.getCardAccount());
                userEarlyWarnOld.setCashAccount(job.getCashAccount());
                userEarlyWarnOld.setNewUserId(sysUser.getUserId());
                userEarlyWarnOld.setOperateId("1");
                userEarlyWarnOld.setUsername(job.getUsername());
                userEarlyWarnOld.setNewId(userEarlyWarnNew.getWarnId());
                userEarlyWarnOld.setPhone(job.getPhone());
                userEarlyWarnOld.setEarlyType("2");
                userEarlyWarnMapper.insert(userEarlyWarnOld);
            });
        }
    }

    private static @NotNull UserEarlyWarn getUserEarlyWarn(SysUser sysUser) {
        UserEarlyWarn userEarlyWarn = new UserEarlyWarn();
        userEarlyWarn.setUserId(sysUser.getUserId());
        userEarlyWarn.setGuid(sysUser.getGuid());
        userEarlyWarn.setUsername(sysUser.getUsername());
        userEarlyWarn.setUserJobNumber(sysUser.getUserJobNumber());
        userEarlyWarn.setCreateBy(sysUser.getUsername());
        userEarlyWarn.setDelFlag("0");
        userEarlyWarn.setResult("1");
        userEarlyWarn.setEarlyType("2");
        userEarlyWarn.setRepeatField("userJobNumber");
        return userEarlyWarn;
    }


    /**
     * 通过value 查出符合条件的key
     *
     * @param map
     * @return
     */
    private static Set<String> findKeysWithValue(Map<String, Long> map) {
        Set<String> keysWithValue = new HashSet<>();
        for (Map.Entry<String, Long> entry : map.entrySet()) {
            if (entry.getValue() > 1L) {
                keysWithValue.add(entry.getKey());
            }
        }
        return keysWithValue;
    }

//    public void pullTemporaryFanWei() {
//
//        int deptSize = 5000;
//        int psnSize = 50000;
//        int staffSize = 50000;
//
//        SysUser sysUser = sysUserMapper.selectOne(Wrappers.<SysUser>lambdaQuery()
//                .eq(SysUser::getIsAdmin, 2)
//                .last("limit 1"));
//
//        if (sysUser != null) {
//            deptSize = StrUtil.isNotBlank(sysUser.getDepartmentAccount())
//                    ? Integer.parseInt(sysUser.getDepartmentAccount()) : deptSize;
//            psnSize = StrUtil.isNotBlank(sysUser.getUserPsnAccount())
//                    ? Integer.parseInt(sysUser.getUserPsnAccount()) : psnSize;
//            staffSize = StrUtil.isNotBlank(sysUser.getUserZhyAccount())
//                    ? Integer.parseInt(sysUser.getUserZhyAccount()) : staffSize;
//        }
//
//        int deptPage = (int) Math.ceil((double) deptSize / 1000) + 1;
//        int psnPage = (int) Math.ceil((double) psnSize / 1000) + 1;
//        int staffPage = (int) Math.ceil((double) staffSize / 1000) + 1;
//
//        //部门
//        log.info("同步泛微OA部门到临时表中 开始时间 time:{}", LocalDateTime.now());
//        for (int dept = 1; dept < deptPage; dept++) {
//            int finalS = dept;
//            threadPoolTaskExecutor().execute(() -> {
//
//                JSONArray departmentArr = pullFanWeiDepartment(finalS).getData();
//                if (null == departmentArr || departmentArr.isEmpty()) {
//                    log.info("[同步泛微OA部门] <<<<<< 同步失败，部门数据为空");
//                    throw new OpenException(CodeSet.SYSTEM_ERR_CODE.getCode(), CodeSet.SYSTEM_ERR_CODE.getCodeName());
//                }
//
//                log.info("同步泛微OA部门数量:{}", departmentArr.size());
//                for (int i = 0, len = departmentArr.size(); i < len; i++) {
//
//                    JSONObject departmentJSON = departmentArr.getJSONObject(i);
//
//                    if (null == departmentJSON) {
//                        continue;
//                    }
//
//                    // 组织机构标识
//                    String deptId = departmentJSON.getString("dept_id");
//
//                    if (StrUtil.isEmpty(deptId)) {
//                        continue;
//                    }
//
//                    // 组织机构名称
//                    String orgName = departmentJSON.getString("org_short_name");
//
//                    if (StrUtil.isEmpty(orgName)) {
//                        // continue;
//                    }
//
//                    Date now = new Date();
//
//                    // 新增部门
//                    TemporaryDepartmentInfo ufDepartInsert = new TemporaryDepartmentInfo();
//
//                    ufDepartInsert.setIndbDate(departmentJSON.getString("indb_date"));
//                    ufDepartInsert.setApplyEvent(departmentJSON.getString("apply_event"));
//                    ufDepartInsert.setDeptId(departmentJSON.getString("dept_id"));
//                    ufDepartInsert.setOrgCode(departmentJSON.getString("org_code"));
//                    ufDepartInsert.setOrgName(departmentJSON.getString("org_name"));
//                    ufDepartInsert.setOrgShortName(departmentJSON.getString("org_short_name"));
//                    ufDepartInsert.setOrgEnName(departmentJSON.getString("org_en_name"));
//                    ufDepartInsert.setOrgLevel(departmentJSON.getString("org_level"));
//                    ufDepartInsert.setOrgType(departmentJSON.getString("org_type"));
//                    ufDepartInsert.setParentId(departmentJSON.getString("parent_id"));
//                    ufDepartInsert.setParentCode(departmentJSON.getString("parent_code"));
//                    ufDepartInsert.setChargePersonCode(departmentJSON.getString("charge_person"));
//                    ufDepartInsert.setOrgOrder(departmentJSON.getString("org_order"));
//                    ufDepartInsert.setOrgStatus(departmentJSON.getString("org_status"));
//
//                    ufDepartInsert.setPullDate(now);
//                    ufDepartInsert.setPullStatus(QWPullStatus.UNSYNC.getCode());
//                    ufDepartInsert.setMasterCreateTime(LocalDateTime.now());
//                    ufDepartInsert.setModifyTime(now);
//                    ufDepartInsert.setCreateTime(now);
//
//                    temporaryDepartmentInfoMapper.insert(ufDepartInsert);
//                }
//            });
//        }
//        log.info("同步泛微OA部门到临时表中 结束时间 time:{}", LocalDateTime.now());
//
//        //人员
//        log.info("同步泛微OA人员到临时表中 开始时间 time:{}", LocalDateTime.now());
//        for (int psn = 1; psn < psnPage; psn++) {
//            int finalS = psn;
//            threadPoolTaskExecutor().execute(() -> {
//                JSONArray psninfoArr = pullFanWeiUserPsn(finalS).getData();
//                log.info("同步泛微OA人员档案结果:{}", psninfoArr);
//                if (null == psninfoArr || 0 >= psninfoArr.size()) {
//                    log.info("[同步泛微OA人员档案] <<<<<< 同步失败，人员档案数据为空");
//                    throw new OpenException(CodeSet.SYSTEM_ERR_CODE.getCode(), CodeSet.SYSTEM_ERR_CODE.getCodeName());
//                }
//
//                log.info("同步泛微OA人员档案数量:{}", psninfoArr.size());
//                for (int i = 0, len = psninfoArr.size(); i < len; i++) {
//
//                    JSONObject psninfoJSON = psninfoArr.getJSONObject(i);
//
//                    if (null == psninfoJSON) {
//                        continue;
//                    }
//
//                    // 员工标识
//                    String psnId = psninfoJSON.getString("psn_id");
//
//                    if (StrUtil.isEmpty(psnId)) {
//                        continue;
//                    }
//
//                    // 2.同步更新 人员档案相关表
//                    Date now = new Date();
//                    TemporaryPsnInfo ufPsnInfoInsert = new TemporaryPsnInfo();
//
//                    ufPsnInfoInsert.setIndbDate(psninfoJSON.getString("indb_date"));
//                    ufPsnInfoInsert.setApplyEvent(psninfoJSON.getString("apply_event"));
//                    ufPsnInfoInsert.setPsnId(psninfoJSON.getString("psn_id"));
//                    ufPsnInfoInsert.setPsnCode(psninfoJSON.getString("psn_code"));
//                    ufPsnInfoInsert.setPsnName(psninfoJSON.getString("psn_name"));
//                    ufPsnInfoInsert.setPsnNamePy(psninfoJSON.getString("psn_name_py"));
//                    ufPsnInfoInsert.setPsnEnName(psninfoJSON.getString("psn_en_name"));
//                    ufPsnInfoInsert.setSex(psninfoJSON.getString("sex"));
//                    ufPsnInfoInsert.setBirthDate(psninfoJSON.getString("birth_date"));
//                    ufPsnInfoInsert.setHomeAddress(psninfoJSON.getString("home_address"));
//                    ufPsnInfoInsert.setMobile(psninfoJSON.getString("mobile"));
//                    ufPsnInfoInsert.setEmail(psninfoJSON.getString("email"));
//                    ufPsnInfoInsert.setOfficePhone(psninfoJSON.getString("office_phone"));
//                    ufPsnInfoInsert.setJoinWorkDate(psninfoJSON.getString("join_work_date"));
//                    ufPsnInfoInsert.setSsdate(psninfoJSON.getString("ssdate"));
//                    ufPsnInfoInsert.setSsnum(psninfoJSON.getString("ssnum"));
//                    ufPsnInfoInsert.setIndbDate(psninfoJSON.getString("induty_date"));
//                    ufPsnInfoInsert.setRegularDate(psninfoJSON.getString("regular_date"));
//                    ufPsnInfoInsert.setSalaryLevel(psninfoJSON.getString("salary_level"));
//                    ufPsnInfoInsert.setSalaryGrade(psninfoJSON.getString("salary_grade"));
//                    ufPsnInfoInsert.setBankName(psninfoJSON.getString("bank_name"));
//                    ufPsnInfoInsert.setBankBranch(psninfoJSON.getString("bank_branch"));
//                    ufPsnInfoInsert.setBankNo(psninfoJSON.getString("bank_no"));
//                    ufPsnInfoInsert.setLineNo(psninfoJSON.getString("line_no"));
//                    ufPsnInfoInsert.setStationNo(psninfoJSON.getString("station_no"));
//                    ufPsnInfoInsert.setPhotoUrl(psninfoJSON.getString("photo_url"));
//                    ufPsnInfoInsert.setPhotoSmallUrl(psninfoJSON.getString("photo_small_url"));
//                    ufPsnInfoInsert.setPsnLevel(psninfoJSON.getString("psn_level"));
//                    ufPsnInfoInsert.setWorkAddress(psninfoJSON.getString("work_address"));
//                    ufPsnInfoInsert.setPsnOrder(psninfoJSON.getString("psn_order"));
//                    ufPsnInfoInsert.setIdcard(psninfoJSON.getString("idcard"));
//
//                    ufPsnInfoInsert.setPullDate(now);
//                    ufPsnInfoInsert.setPullStatus(QWPullStatus.UNSYNC.getCode().toString());
//                    ufPsnInfoInsert.setCreateTime(now);
//                    ufPsnInfoInsert.setModifyTime(now);
//                    ufPsnInfoInsert.setId(System.currentTimeMillis());
//                    ufPsnInfoInsert.setIsInsert(2);
//                    ufPsnInfoInsert.setMasterCreateTime(LocalDateTime.now());
//                    temporaryPsnInfoMapper.insert(ufPsnInfoInsert);
//                }
//            });
//        }
//        log.info("同步泛微OA人员到临时表中 结束时间 time:{}", LocalDateTime.now());
//
//        //职务
//        log.info("同步泛微OA职务到临时表中 开始时间 time:{}", LocalDateTime.now());
//        for (int staff = 1; staff < staffPage; staff++) {
//            int finalS = staff;
//            threadPoolTaskExecutor().execute(() -> {
//                JSONArray zhyinfoArr = pullFanWeiUserZhy(finalS).getData();
//
//                log.info("页码:{},同步泛微OA人员任职结果 :{}", zhyinfoArr, finalS);
//                if (null == zhyinfoArr || 0 >= zhyinfoArr.size()) {
//                    log.info("[同步泛微OA人员任职] <<<<<< 同步失败，人员任职数据为空");
//                    throw new OpenException(CodeSet.SYSTEM_ERR_CODE.getCode(), CodeSet.SYSTEM_ERR_CODE.getCodeName());
//                }
//                for (int i = 0, len = zhyinfoArr.size(); i < len; i++) {
//
//                    JSONObject zhyinfoJSON = zhyinfoArr.getJSONObject(i);
//
//                    if (null == zhyinfoJSON) {
//                        continue;
//                    }
//
//                    // 员工标识
//                    String psnId = zhyinfoJSON.getString("psn_id");
//
//                    if (StrUtil.isEmpty(psnId)) {
//                        continue;
//                    }
//                    // 2.同步更新 人员任职相关表
//                    Date now = new Date();
//
//                    TemporaryStaffInfo ufZhyInfoInsert = new TemporaryStaffInfo();
//
//                    ufZhyInfoInsert.setDutyId(zhyinfoJSON.getString("duty_id"));
//                    ufZhyInfoInsert.setPsnId(zhyinfoJSON.getString("psn_id"));
//                    ufZhyInfoInsert.setCorpId(zhyinfoJSON.getString("corp_id"));
//                    ufZhyInfoInsert.setDeptId(zhyinfoJSON.getString("dept_id"));
//                    ufZhyInfoInsert.setOrgCode(zhyinfoJSON.getString("org_code"));
//                    ufZhyInfoInsert.setIndutyDate(zhyinfoJSON.getString("induty_date"));
//                    ufZhyInfoInsert.setOnpostDate(zhyinfoJSON.getString("onpost_date"));
//                    ufZhyInfoInsert.setPnsClass(zhyinfoJSON.getString("pns_class"));
//                    ufZhyInfoInsert.setPnsClassName(zhyinfoJSON.getString("pns_class_name"));
//                    ufZhyInfoInsert.setPnsJob(zhyinfoJSON.getString("pns_job"));
//                    ufZhyInfoInsert.setIsLeader(zhyinfoJSON.getString("is_leader"));
//                    ufZhyInfoInsert.setPnsOrder(zhyinfoJSON.getString("pns_order"));
//                    ufZhyInfoInsert.setClassPosition(zhyinfoJSON.getString("class_position"));
//                    ufZhyInfoInsert.setGradePosition(zhyinfoJSON.getString("grade_position"));
//                    ufZhyInfoInsert.setDutyCode(zhyinfoJSON.getString("duty_code"));
//                    ufZhyInfoInsert.setDutyType(zhyinfoJSON.getString("duty_type"));
//                    ufZhyInfoInsert.setJobCode(zhyinfoJSON.getString("job_code"));
//                    ufZhyInfoInsert.setJobStatus(zhyinfoJSON.getString("job_status"));
//                    ufZhyInfoInsert.setBeginTime(zhyinfoJSON.getString("begin_time"));
//                    ufZhyInfoInsert.setEndTime(zhyinfoJSON.getString("end_time"));
//
//                    ufZhyInfoInsert.setPullDate(now);
//                    ufZhyInfoInsert.setPullStatus(QWPullStatus.UNSYNC.getCode().toString());
//                    ufZhyInfoInsert.setCreateTime(now);
//                    ufZhyInfoInsert.setModifyTime(now);
//                    ufZhyInfoInsert.setId(System.currentTimeMillis());
//                    temporaryStaffInfoMapper.insert(ufZhyInfoInsert);
//                }
//            });
//        }
//        log.info("同步泛微OA职务到临时表中 结束时间 time:{}", LocalDateTime.now());
//    }

    /**
     * 从临时表中insert到部门表中
     */
    public void insertDepartment() {
        //拉去部门表中的信息 筛选出当天的信息
        List<TemporaryDepartmentInfo> temporaryDepartmentInfoList = temporaryDepartmentInfoService
                .list(Wrappers.<TemporaryDepartmentInfo>lambdaQuery()
                        .eq(TemporaryDepartmentInfo::getIsInsert, 2));

        //现目前存在的部门名称
        List<String> deptNameList = new ArrayList<>(userDepartmentInfoMapper
                .selectList(null)
                .stream()
                .filter(Objects::nonNull)
                .map(UserDepartmentInfo::getDeptId).toList());


        temporaryDepartmentInfoList.stream().filter(Objects::nonNull)
                .filter(d -> StrUtil.isNotBlank(d.getDeptId()))
                .distinct().forEach(a -> {
                    UserDepartmentInfo userDepartmentInfo = new UserDepartmentInfo();
                    userDepartmentInfo.setIndbDate(a.getIndbDate());
                    userDepartmentInfo.setApplyEvent(a.getApplyEvent());
                    userDepartmentInfo.setDeptId(a.getDeptId());
                    userDepartmentInfo.setOrgCode(a.getOrgCode());
                    userDepartmentInfo.setOrgName(a.getOrgName());
                    userDepartmentInfo.setOrgShortName(a.getOrgShortName());
                    userDepartmentInfo.setOrgEnName(a.getOrgEnName());
                    userDepartmentInfo.setOrgLevel(a.getOrgLevel());
                    userDepartmentInfo.setOrgType(a.getOrgType());
                    userDepartmentInfo.setParentId(a.getParentId());
                    userDepartmentInfo.setParentCode(a.getParentCode());
                    userDepartmentInfo.setChargePersonCode(a.getChargePersonCode());
                    userDepartmentInfo.setOrgOrder(a.getOrgOrder());
                    userDepartmentInfo.setOrgStatus(a.getOrgStatus());
                    userDepartmentInfo.setCreateTime(a.getCreateTime());
                    userDepartmentInfo.setModifyTime(a.getModifyTime());
                    userDepartmentInfo.setPullDate(a.getPullDate());
                    userDepartmentInfo.setPullStatus(a.getPullStatus());
                    userDepartmentInfo.setMasterCreateTime(LocalDateTime.now());
                    userDepartmentInfo.setIsInsert(2);

                    if (deptNameList.contains(a.getDeptId())) {
                        userDepartmentInfo.setPullStatus(2);
                        userDepartmentInfoMapper.update(userDepartmentInfo, Wrappers.<UserDepartmentInfo>lambdaUpdate()
                                .eq(UserDepartmentInfo::getDeptId, a.getDeptId()));
                    }
                    if (!deptNameList.contains(a.getDeptId())) {
                        deptNameList.add(a.getDeptId());
                        userDepartmentInfo.setPullStatus(1);
                        userDepartmentInfoMapper.insert(userDepartmentInfo);
                    }
                    a.setIsInsert(1);
                });

        log.info("修改泛微临时表中的inset状态 个数 size:{}", temporaryDepartmentInfoList.size());
        temporaryDepartmentInfoService.updateBatchById(temporaryDepartmentInfoList);
    }

    /**
     * 从临时表中insert到人员表中
     */
    public void insertPsnUser() {
        //拉去部门表中的信息 筛选出当天的信息
        List<TemporaryPsnInfo> temporaryPsnInfoList = temporaryPsnInfoService
                .list(Wrappers.<TemporaryPsnInfo>lambdaQuery()
                        .eq(TemporaryPsnInfo::getIsInsert, 2));

        List<String> userPsnInfoList = new ArrayList<>(userPsnInfoService.list()
                .stream().filter(Objects::nonNull)
                .map(UserPsnInfo::getPsnId).toList());


        List<UserPsnInfo> userPsnInfoAddList = new ArrayList<>();

        temporaryPsnInfoList.stream().filter(Objects::nonNull)
                .filter(d -> StrUtil.isNotBlank(d.getPsnId())).distinct().forEach(a -> {
                    UserPsnInfo userPsnInfo = new UserPsnInfo();
                    userPsnInfo.setIndbDate(a.getIndbDate());
                    userPsnInfo.setApplyEvent(a.getApplyEvent());
                    userPsnInfo.setPsnId(a.getPsnId());
                    userPsnInfo.setPsnCode(a.getPsnCode());
                    userPsnInfo.setPsnName(a.getPsnName());
                    userPsnInfo.setPsnNamePy(a.getPsnNamePy());
                    userPsnInfo.setPsnEnName(a.getPsnEnName());
                    userPsnInfo.setSex(a.getSex());
                    userPsnInfo.setBirthDate(a.getBirthDate());
                    userPsnInfo.setHomeAddress(a.getHomeAddress());
                    userPsnInfo.setMobile(a.getMobile());
                    userPsnInfo.setEmail(a.getEmail());
                    userPsnInfo.setOfficePhone(a.getOfficePhone());
                    userPsnInfo.setJoinWorkDate(a.getJoinWorkDate());
                    userPsnInfo.setSsdate(a.getSsdate());
                    userPsnInfo.setSsnum(a.getSsnum());
                    userPsnInfo.setIndutyDate(a.getIndutyDate());
                    userPsnInfo.setRegularDate(a.getRegularDate());
                    userPsnInfo.setSalaryLevel(a.getSalaryLevel());
                    userPsnInfo.setSalaryGrade(a.getSalaryGrade());
                    userPsnInfo.setBankName(a.getBankName());
                    userPsnInfo.setBankBranch(a.getBankBranch());
                    userPsnInfo.setBankNo(a.getBankNo());
                    userPsnInfo.setLineNo(a.getLineNo());
                    userPsnInfo.setStationNo(a.getStationNo());
                    userPsnInfo.setPhotoUrl(a.getPhotoUrl());
                    userPsnInfo.setPhotoSmallUrl(a.getPhotoSmallUrl());
                    userPsnInfo.setPsnLevel(a.getPsnLevel());
                    userPsnInfo.setWorkAddress(a.getWorkAddress());
                    userPsnInfo.setPsnOrder(a.getPsnOrder());
                    userPsnInfo.setIdcard(a.getIdcard());
                    userPsnInfo.setCreateTime(a.getCreateTime());
                    userPsnInfo.setModifyTime(a.getModifyTime());
                    userPsnInfo.setPullDate(a.getPullDate());
                    userPsnInfo.setPullStatus(a.getPullStatus());
                    userPsnInfo.setUserId(a.getUserId());
                    userPsnInfo.setIsInsert(2);
                    userPsnInfo.setMasterCreateTime(a.getMasterCreateTime());
                    if (userPsnInfoList.contains(a.getPsnId())) {
                        userPsnInfoService.update(userPsnInfo, Wrappers.<UserPsnInfo>lambdaUpdate()
                                .eq(UserPsnInfo::getPsnId, a.getPsnId()));
                    }
                    if (!userPsnInfoList.contains(a.getPsnId())) {
                        userPsnInfoAddList.add(userPsnInfo);
                    }
                    a.setIsInsert(1);
                });

        temporaryPsnInfoService.updateBatchById(temporaryPsnInfoList);

        if (!userPsnInfoAddList.isEmpty()) {
            log.info("用户同步新增 个数 size:{}", userPsnInfoAddList.size());
            userPsnInfoService.saveBatch(userPsnInfoAddList);
        }

    }

    /**
     * 从临时表中insert到任职表中
     */
    public void insertStaff() {
        //拉去部门表中的信息 筛选出当天的信息
        List<TemporaryStaffInfo> temporaryStaffInfoList = temporaryStaffInfoService
                .list(Wrappers.<TemporaryStaffInfo>lambdaQuery()
                        .eq(TemporaryStaffInfo::getIsInsert, 2));

        List<String> userStaffList = new ArrayList<>(userStaffInfoMapper.selectList(null)
                .stream().filter(Objects::nonNull)
                .map(UserStaffInfo::getPsnId).toList());


        temporaryStaffInfoList.forEach(cc -> {
            UserStaffInfo userStaffInfo = new UserStaffInfo();
            userStaffInfo.setDutyId(cc.getDutyId());
            userStaffInfo.setApplyEvent(cc.getApplyEvent());
            userStaffInfo.setPsnId(cc.getPsnId());
            userStaffInfo.setCorpId(cc.getCorpId());
            userStaffInfo.setDeptId(cc.getDeptId());
            userStaffInfo.setOrgCode(cc.getOrgCode());
            userStaffInfo.setIndutyDate(cc.getIndutyDate());
            userStaffInfo.setOnpostDate(cc.getOnpostDate());
            userStaffInfo.setPnsClass(cc.getPnsClass());
            userStaffInfo.setPnsClassName(cc.getPnsClassName());
            userStaffInfo.setPnsJob(cc.getPnsJob());
            userStaffInfo.setIsLeader(cc.getIsLeader());
            userStaffInfo.setPnsOrder(cc.getPnsOrder());
            userStaffInfo.setClassPosition(cc.getClassPosition());
            userStaffInfo.setGradePosition(cc.getGradePosition());
            userStaffInfo.setDutyCode(cc.getDutyCode());
            userStaffInfo.setDutyType(cc.getDutyType());
            userStaffInfo.setJobCode(cc.getJobCode());
            userStaffInfo.setJobStatus(cc.getJobStatus());
            userStaffInfo.setBeginTime(cc.getBeginTime());
            userStaffInfo.setEndTime(cc.getEndTime());
            userStaffInfo.setCreateTime(cc.getCreateTime());
            userStaffInfo.setModifyTime(cc.getModifyTime());
            userStaffInfo.setPullDate(cc.getPullDate());
            userStaffInfo.setPullStatus(cc.getPullStatus());
            userStaffInfo.setUserId(cc.getUserId());
            userStaffInfo.setMasterCreateTime(cc.getMasterCreateTime());
            userStaffInfo.setIsInsert(2);
            if (userStaffList.contains(cc.getPsnId())) {
                userStaffInfoMapper.update(userStaffInfo, Wrappers.<UserStaffInfo>lambdaUpdate()
                        .eq(UserStaffInfo::getPsnId, cc.getPsnId()));
            }

            if (!userStaffList.contains(cc.getPsnId())) {
                userStaffList.add(cc.getPsnId());
                userStaffInfoMapper.insert(userStaffInfo);
            }
            cc.setIsInsert(1);
        });

        temporaryStaffInfoService.updateBatchById(temporaryStaffInfoList);
    }
}
